package com.Jano.annotation.aop;


import com.Jano.annotation.LogAnnotation;
import com.Jano.entity.OperationLog;
import com.Jano.model.UserModel;
import com.Jano.service.OperationLogService;
import com.Jano.util.IPUtil;
import com.alibaba.fastjson.JSON;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

@Component
@Aspect
public class LogAspect {
    @Autowired
    OperationLogService operationLogService;

    /**
     * 此处的切点是注解的方式
     * 只要出现 @LogAnnotation注解都会进入
     */
    @Around("@annotation(com.Jano.annotation.LogAnnotation)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {

        long before = System.currentTimeMillis();
        //执行目标方法
        Object returnResult = joinPoint.proceed();
        long end = System.currentTimeMillis();
        //计算目标方法的执行时间
        long time = end - before;
        this.saveLog(time, joinPoint);
        return returnResult;

    }

    /*
     *1.收集日志信息
     *2.日志持久化
     */
    public void saveLog(long time, ProceedingJoinPoint jp) {
        Integer logUserId = null;
        String logUsername = null;
        String logOperation = null;
        String logMethod = null;
        String logParams = null;
        String logIp = null;
        //计算数据
        //1.记录时间
        Date logCreateTime = new Date();
        //说ServletRequestAttributes是RequestAttributes的子类，所以直接强转就可以了 通过强转后的ServletRequestAttributes直接getRequest，即可得到request对象。
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        UserModel sessionUser = (UserModel) request.getSession().getAttribute("sessionUser");
        if (sessionUser != null) {
            //2.用户ID
            logUserId = sessionUser.getId();
            //3.用户名
            logUsername = sessionUser.getUsername();
        }
        //4.IP地址
        logIp = IPUtil.getIpAddr(request);

        Signature signature = jp.getSignature();
        if (signature instanceof MethodSignature) {
            MethodSignature methodSignature = (MethodSignature) signature;
            Method method = methodSignature.getMethod();
            LogAnnotation annotation = method.getAnnotation(LogAnnotation.class);
            String action = annotation.action();
            String title = annotation.title();
            //5.操作
            logOperation = title + "-" + action;
            //6.方法信息
            logMethod = methodSignature.toString();
            //7.入参
            Object[] args = jp.getArgs();
            logParams = JSON.toJSONString(args);
        }

        OperationLog log = new OperationLog();
        log.setUserId(logUserId);
        log.setUsername(logUsername);
        log.setParams(logParams);
        log.setCreateTime(logCreateTime);
        log.setOperation(logOperation);
        log.setMethod(logMethod);
        log.setIp(logIp);
        log.setTime(time);
        operationLogService.addOperationLog(log);
    }
}
